Skip to content

Đăng ký phân tích thị trường tổng thể

Môi trường production: https://stream.valuescan.ai


1. Tổng quan

Phân tích thị trường tổng thể là kết quả ValueAgent tổng hợp đa chiều về diễn biến BTC/ETH. Đăng ký thị trường là cơ chế máy chủ chủ động đẩy: sau khi người dùng đăng ký, khi tình hình thị trường rộng thay đổi, máy chủ đẩy nội dung phân tích dạng văn bản tới client qua kênh SSE.


2. URL đăng ký

GET https://stream.valuescan.ai/stream/market/subscribe

Tham số xác thực (query string):

Tham sốKiểuBắt buộcMô tả
apiKeystringValueScan Access Key
signstringChữ ký HMAC-SHA256
timestamplongUnix timestamp đơn vị mili giây
noncestringChuỗi ngẫu nhiên (chống replay)

Thuật toán ký:

sign = HMAC-SHA256(SK, timestampMs + nonce)

Trong đó timestampMs là chuỗi timestamp Unix tính bằng mili giây nối với nonce.


3. Định dạng sự kiện SSE

Kết nối thành công

event: connected
data: subscribed

Heartbeat (duy trì kết nối)

: heartbeat

event: heartbeat
data: ping

Máy chủ gửi heartbeat mỗi 20 giây.

Đẩy phân tích thị trường

event: market
data: {"ts":1775604300144,"uniqueId":"phan_tich_thi_truong_20260408103000","content":"BTC chi phối thị trường, dòng tiền tập trung cao; nên theo dõi diễn biến BTC."}

Các trường payload sự kiện market:

TrườngKiểuMô tả
tslongThời điểm đẩy (timestamp mili giây)
uniqueIdstringĐịnh danh duy nhất (để khử trùng lặp)
contentstringNội dung phân tích thị trường dạng văn bản thuần

4. Ví dụ đăng ký

Python

python
import hashlib
import hmac
import json
import time
import uuid
import urllib.request
from urllib.parse import urlencode

AK = "your-access-key"
SK = "your-secret-key"

ts = int(time.time() * 1000)
nonce = uuid.uuid4().hex
sign = hmac.new(
    SK.encode(),
    (str(ts) + nonce).encode(),
    hashlib.sha256,
).hexdigest()

params = urlencode({
    "apiKey": AK,
    "sign": sign,
    "timestamp": ts,
    "nonce": nonce,
})

url = f"https://stream.valuescan.ai/stream/market/subscribe?{params}"
req = urllib.request.Request(url, headers={"Accept": "text/event-stream"})

with urllib.request.urlopen(req, timeout=300) as resp:
    event_name = ""
    data_str = ""
    for raw in resp:
        line = raw.decode("utf-8").rstrip("\r\n")

        if line.startswith(":"):
            print("♥ Heartbeat")
            continue

        if line == "":
            if data_str:
                handle_event(event_name, data_str)
            event_name = ""
            data_str = ""
        elif line.startswith("event:"):
            event_name = line[6:].strip()
        elif line.startswith("data:"):
            data_str = line[5:].strip()


def handle_event(event_name: str, data_str: str) -> None:
    if event_name == "connected":
        print(f"[Đã kết nối] {data_str}")
    elif event_name == "market":
        payload = json.loads(data_str)
        ts = payload["ts"]
        content = payload["content"]
        dt = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts / 1000))
        print(f"[Phân tích thị trường {dt}] {content}")

cURL (kiểm tra nhanh)

bash
python3 -c "
import hashlib, hmac, time, uuid, urllib.parse
SK='your-secret-key'
ts=int(time.time()*1000)
nonce=uuid.uuid4().hex
sign=hmac.new(SK.encode(), (str(ts)+nonce).encode(), hashlib.sha256).hexdigest()
params=urllib.parse.urlencode({'apiKey':'your-access-key','sign':sign,'timestamp':ts,'nonce':nonce})
print(f"curl -N 'https://stream.valuescan.ai/stream/market/subscribe?{params}' -H 'Accept: text/event-stream'")
'"

5. Kết nối lại khi mất kết nối

Giống đăng ký tín hiệu: nên dùng exponential backoff khi kết nối lại:

python
def listen_with_retry(url: str, max_retries: int = 10) -> None:
    retries = 0
    while retries <= max_retries:
        try:
            req = urllib.request.Request(url, headers={"Accept": "text/event-stream"})
            with urllib.request.urlopen(req, timeout=300) as resp:
                _read_sse(resp)
                break
        except KeyboardInterrupt:
            print("Người dùng ngắt, thoát.")
            break
        except Exception as e:
            retries += 1
            wait = min(2 ** retries, 60)
            print(f"Mất kết nối ({e}), lần kết nối lại thứ {retries} sau {wait} giây...")
            time.sleep(wait)
    else:
        print("Hết số lần thử, thoát.")

6. Mã lỗi

Mã HTTPMô tả
200Kết nối thành công
400Thiếu tham số hoặc định dạng sai
401Xác thực chữ ký thất bại hoặc timestamp ngoài phạm vi
404URL đăng ký sai
503Dịch vụ không khả dụng (lỗi kết nối backend xác thực)